package com.helper;

import com.Utils.ExcelUtils;
import com.exception.TemplateException;

import java.io.FileInputStream;
import java.util.*;

/**
 * 读取excel所有数据完成类转换
 */

public class ExcelToBeanConvertor<T> {

    /**
     * 验证表头
     * @param titles 规定的表头
     * @param map  excel的数据
     * @return  true 表头符合   false模板不匹配
     */

    public boolean validSheetTitles(String[] titles, Map<String, List<Object[]>> map){
        boolean b = false;
        for (Map.Entry<String, List<Object[]>> entry : map.entrySet()) {
            List<Object[]> value = entry.getValue();
                Object[] objects = value.get(0);
                b = Arrays.equals(titles, objects);
        }
        return b;
    }

    /**
     * 按照指定的模板格式读取excel数据,封装至Map<String, List<T>对象集合中,所有符合模板格式的sheet页
     * mao的键值对的格式是: <sheet页名称, List<T>
     * @param titles   模板格式信息
     * @param in     输入流
     * @param cls    类实例
     * @return   当excel数据不符合指定的模板的格式时将抛出
     * 异常InvalidExcelTemplateException
     */
    public Map<String,List<T>> readToBeanMap(String[] titles, FileInputStream in, Class<T> cls) {
        //返回的数据类型
        Map<String,List<T>> map = new HashMap<String, List<T>>();
        //读取所有数据
        Map<String, List<Object[]>> listmap = ExcelUtils.readTomap(in);
        //验证表头
        boolean b = validSheetTitles(titles, listmap);
        //表头有问题模板的格式时将抛出
        if (!b){
            throw new TemplateException("模板异常!");
        }
        //创建类转换器的对象
        BeanGenerator<T> generator = new BeanGenerator<T>();
        for (Map.Entry<String, List<Object[]>> entry : listmap.entrySet()) {
            //去掉表头
            List<Object[]> value = entry.getValue();
            value.remove(0);
            //创建要返回的集合
            List<T> list = new ArrayList<T>();
            //把每一行数据转成对象
            for (Object[] objects : value) {
                T bean = generator.generateBean(cls, objects);
               // System.out.println(bean);
                list.add(bean);
            }
            map.put(entry.getKey(),list);
        }
        return map;
    }
}
